#include "main.hpp"

const char *AP_NAME = "配网WIFI"; // wifi名字
extern char sta_ssid[32], sta_password[32];

WiFiUDP ntpUDP;
#define LED_PIN 12
#define NUMPIXELS 6
extern IPAddress apIP;
Ticker tickerSyncTask, ledAnimationTask;
Adafruit_NeoPixel led(NUMPIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);
NTPClient timeClient(ntpUDP, "ntp1.aliyun.com", 60 * 60 * 8, 30 * 60 * 1000);
DeviceConf deviceConf = {0};

void initBasic(void)
{ //初始化基础
  Serial.begin(115200);
  WiFi.hostname("Smart-ESP8266"); //设置ESP8266设备名
  // SPIFFS.format();
  if (SPIFFS.begin())
  { // 启动SPIFFS
    Serial.println("SPIFFS Started.");
  }
  else
  {
    Serial.println("SPIFFS Failed to Start.");
  }
  // SaveConf();
  LoadConf();
  PrintConf();
  ledAnimationTask.attach_ms(100, LEDAnimationTask);

  led.begin();
  led.setBrightness(255);
  ApplyConf();
  timeClient.setTimeOffset(60 * 60 * deviceConf.timezoneOffset_);
  delay(50);
}

void initSoftAP(void)
{ //初始化AP模式
  // WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  if (WiFi.softAP(AP_NAME))
  {
    Serial.println("ESP8266 SoftAP is right");
  }
}

void SyncTask()
{
  Serial.println(timeClient.getFormattedTime());
  u8 *data = NULL;
  u8 len = GenSetTimeData(timeClient.getHours(), timeClient.getMinutes(), timeClient.getSeconds(), &data);
  if (data)
  {
    for (size_t i = 0; i < len; i++)
      // Serial.print(data[i]);
      Serial.write(data[i]);
    free(data);
  }
}

void LEDDynamicInit()
{
  led.setPixelColor(0, led.Color(255, 0, 0));
  led.setPixelColor(1, led.Color(153, 102, 0));
  led.setPixelColor(2, led.Color(51, 204, 0));
  led.setPixelColor(3, led.Color(0, 204, 51));
  led.setPixelColor(4, led.Color(0, 102, 153));
  led.setPixelColor(5, led.Color(0, 0, 255));
  led.show(); //刷新显示
}

void LEDAnimationTask()
{
  static u8 way = 0;
  if (deviceConf.ledMode_ == LED_MODE_DYNAMIC || deviceConf.ledMode_ == LED_MODE_DYNAMIC_BREATH) //跑马灯
  {
    for (int i = 0; i < NUMPIXELS; i++)
    {
      uint32_t curColor = led.getPixelColor(i);
      if ((curColor & 0xFF0000) && !(curColor & 0xFF))
        curColor = (((((curColor)&0xFF0000) >> 16) - 51) << 16) | ((((curColor & 0x00FF00) >> 8) + 51) << 8);
      else if (curColor & 0xFF00)
        curColor = (((((curColor)&0x00FF00) >> 8) - 51) << 8) | ((((curColor & 0x0000FF)) + 51));
      else
        curColor = ((((curColor & 0x0000FF)) - 51)) | (((((curColor)&0xFF0000) >> 16) + 51) << 16);
      led.setPixelColor(i, curColor);
    }
  }
  if (deviceConf.ledMode_ == LED_MODE_DYNAMIC_BREATH || deviceConf.ledMode_ == LED_MODE_STATIC_BREATH) //呼吸灯
  {
    u8 bright = led.getBrightness();
    if (bright + 10 > 255)
      way = 0;
    if (bright - 10 < 0)
      way = 1;
    if (way)
      bright += 10;
    else
      bright -= 10;
    led.setBrightness(bright);
  }
  led.show();
}

void WriteConf()
{
  u8 *data = NULL;
  u8 len = GenSetConfData(&deviceConf, &data);
  if (data)
  {
    for (size_t i = 0; i < len; i++)
      Serial.write(data[i]);
    free(data);
  }
}

void ApplyConf()
{
  if (deviceConf.ledState_)
  {
    if (deviceConf.ledMode_ == LED_MODE_STATIC || deviceConf.ledMode_ == LED_MODE_STATIC_BREATH)
      led.fill(deviceConf.colorValue_, 0, NUMPIXELS);
    if (deviceConf.ledMode_ == LED_MODE_DYNAMIC || deviceConf.ledMode_ == LED_MODE_DYNAMIC_BREATH)
      LEDDynamicInit();
  }
  else
    led.clear();
  led.show();
  timeClient.setTimeOffset(60 * 60 * deviceConf.timezoneOffset_);
  timeClient.update();
  SyncTask();
}

void connectNewWifi(char *ssid, char *passwd)
{
  static int firstRunFlag = 0;
  WiFi.mode(WIFI_AP_STA);    //切换为STA模式
  WiFi.setAutoConnect(true); //设置自动连接
  if (!firstRunFlag)
  {
    WiFi.begin(); //连接上一次连接成功的wifi
  }
  else
  {
    WiFi.persistent(true);
    WiFi.begin(ssid, passwd); //连接上一次连接成功的wifi
  }
  Serial.println("");
  Serial.print("Connect to wifi");
  int count = 0;
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    count++;
    if (count > 40)
    { //如果5秒内没有连上，就开启Web配网 可适当调整这个时间
      initSoftAP();
      initWebServer();
      initDNS();
      firstRunFlag++;
      break; //跳出 防止无限初始化
    }
    Serial.print(".");
  }
  Serial.println("");
  if (WiFi.status() == WL_CONNECTED)
  { //如果连接上 就输出IP信息 防止未连接上break后会误输出
    Serial.println("WIFI Connected!");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP()); //打印esp8266的IP地址
    timeClient.begin();
    initConfWeb();
  }
}

void PrintConf()
{
  String str = "ledState: " + String(deviceConf.ledState_);
  Serial.println(str);
  str = "ledMode: " + String(deviceConf.ledMode_);
  Serial.println(str);
  str = "timezoneOffset_: " + String(deviceConf.timezoneOffset_);
  Serial.println(str);
  str = "envDataEnable_: " + String(deviceConf.envDataEnable_);
  Serial.println(str);
  str = "colorValue_: " + String(deviceConf.colorValue_);
  Serial.println(str);
  str = "startSleepTime_: " + String(deviceConf.startSleepTime_);
  Serial.println(str);
  str = "endSleepTime_: " + String(deviceConf.endSleepTime_);
  Serial.println(str);
}

void setup()
{
  initBasic();
  connectNewWifi("", "");
}

void loop()
{
  static bool initFlag = false;
  WebServerProcess();
  if (WiFi.status() == WL_CONNECTED)
  {
    timeClient.update();
    if (timeClient.isTimeSet() && !initFlag)
    {
      delay(20 * 1000);
      initFlag = true;
      WriteConf();
      delay(1000);
      SyncTask();
      tickerSyncTask.attach(30 * 60, SyncTask);
    }
    delay(10);
  }
}